package com.mvc.core.utils.task;
/**
* @author 李涛
* @version 创建时间：2018年8月26日 下午6:26:40
* 类说明
*/

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class WorkerThreadPool {

	/**
	 * 声明线程池
	 */
	private ExecutorService exc = Executors.newCachedThreadPool();
	/**
	 * 包装队列线程池
	 */
	private CompletionService<WorkerResult> sc = new ExecutorCompletionService<>(exc);

	/**
	 * 任务长度
	 */
	public volatile int length;

	public synchronized Future<WorkerResult> submit(Worker worker) {
		length++;
		return sc.submit(worker);
	}

	/**
	 * 阻塞获取,适合串行
	 * 
	 * @param key
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public WorkerResult get() throws InterruptedException, ExecutionException {
		return sc.take().get();
	}

	/**
	 * 最快速执行代码
	 * 
	 * @return
	 * @throws Exception
	 */
	public void shutDown() throws Exception {
		exc.shutdown();
	}

	/**
	 * 添加任务明细
	 */
	static class Worker implements Callable<WorkerResult> {

		private String key;
		private Object param;
		private WorkContents work;

		public Worker(String key, Object param, WorkContents doWork) {
			if (key == null || doWork == null) {
				throw new NullPointerException();
			}
			this.key = key;
			this.work = doWork;
			this.param = param;
		}

		@Override
		public WorkerResult call() throws Exception {
			// 执行业务代码
			Object rs = work.doWork(param);
			return new WorkerResult(this.key, rs);
		}

		public String getKey() {
			return key;
		}

		public void setKey(String key) {
			this.key = key;
		}

	}

	/**
	 * 执行返回结果
	 *
	 */
	static class WorkerResult {

		private String key;
		private Object value;

		public WorkerResult(String key, Object value) {
			this.key = key;
			this.setValue(value);
		}

		public String getKey() {
			return key;
		}

		public void setKey(String key) {
			this.key = key;
		}

		public Object getValue() {
			return value;
		}

		public void setValue(Object value) {
			this.value = value;
		}

	}

	/***
	 * 执行业务代码
	 */
	public interface WorkContents {
		Object doWork(Object param) throws Exception;
	}

}
